using GameFramework.Editor.Utility;
using UnityEditor;

namespace GameFramework.Editor
{
    public partial class Menus
    {
        public static class Log
        {
            // ReSharper disable once MemberHidesStaticFromOuterClass
            private const string MenuRoot = Menus.MenuRoot + "/Log";

            private const string MenuItemAll = MenuRoot + "/All";
            private const string MenuItemDebug = MenuRoot + "/Debug";
            private const string MenuItemWarning = MenuRoot + "/Warning";
            private const string MenuItemInfo = MenuRoot + "/Info";
            private const string MenuItemError = MenuRoot + "/Error";
            private const string MenuItemFatal = MenuRoot + "/Fatal";
            private const string MenuItemException = MenuRoot + "/Exception";

            private const string ScriptingDefineSymbolDebug = "ENABLE_LOG_DEBUG";
            private const string ScriptingDefineSymbolWarning = "ENABLE_LOG_WARNING";
            private const string ScriptingDefineSymbolInfo = "ENABLE_LOG_INFO";
            private const string ScriptingDefineSymbolError = "ENABLE_LOG_ERROR";
            private const string ScriptingDefineSymbolFatal = "ENABLE_LOG_FATAL";
            private const string ScriptingDefineSymbolException = "ENABLE_LOG_EXCEPTION";

            private static string[] ScriptingDefineSymbols => new[]
            {
                ScriptingDefineSymbolDebug,
                ScriptingDefineSymbolWarning,
                ScriptingDefineSymbolInfo,
                ScriptingDefineSymbolError,
                ScriptingDefineSymbolFatal,
                ScriptingDefineSymbolException
            };

            [MenuItem(MenuItemDebug, false, 100)]
            public static void ToggleLogDebug()
            {
                ScriptingDefineSymbolsUtility.Toggle(ScriptingDefineSymbolDebug);
            }

            [MenuItem(MenuItemDebug, true)]
            public static bool ToggleLogDebugValidate()
            {
                Menu.SetChecked(MenuItemDebug, ScriptingDefineSymbolsUtility.Contains(ScriptingDefineSymbolDebug));
                return true;
            }

            [MenuItem(MenuItemWarning, false, 100)]
            public static void ToggleLogWarning()
            {
                ScriptingDefineSymbolsUtility.Toggle(ScriptingDefineSymbolWarning);
            }

            [MenuItem(MenuItemWarning, true)]
            public static bool ToggleLogWarningValidate()
            {
                Menu.SetChecked(MenuItemWarning, ScriptingDefineSymbolsUtility.Contains(ScriptingDefineSymbolWarning));
                return true;
            }

            [MenuItem(MenuItemInfo, false, 100)]
            public static void ToggleLogInfo()
            {
                ScriptingDefineSymbolsUtility.Toggle(ScriptingDefineSymbolInfo);
            }

            [MenuItem(MenuItemInfo, true)]
            public static bool ToggleLogInfoValidate()
            {
                Menu.SetChecked(MenuItemInfo, ScriptingDefineSymbolsUtility.Contains(ScriptingDefineSymbolInfo));
                return true;
            }

            [MenuItem(MenuItemError, false, 100)]
            public static void ToggleLogError()
            {
                ScriptingDefineSymbolsUtility.Toggle(ScriptingDefineSymbolError);
            }

            [MenuItem(MenuItemError, true)]
            public static bool ToggleLogErrorValidate()
            {
                Menu.SetChecked(MenuItemError, ScriptingDefineSymbolsUtility.Contains(ScriptingDefineSymbolError));
                return true;
            }

            [MenuItem(MenuItemFatal, false, 100)]
            public static void ToggleLogFatal()
            {
                ScriptingDefineSymbolsUtility.Toggle(ScriptingDefineSymbolFatal);
            }

            [MenuItem(MenuItemFatal, true)]
            public static bool ToggleLogFatalValidate()
            {
                Menu.SetChecked(MenuItemFatal, ScriptingDefineSymbolsUtility.Contains(ScriptingDefineSymbolFatal));
                return true;
            }
            
            [MenuItem(MenuItemException, false, 100)]
            public static void ToggleLogException()
            {
                ScriptingDefineSymbolsUtility.Toggle(ScriptingDefineSymbolException);
            }
            
            [MenuItem(MenuItemException, true)]
            public static bool ToggleLogExceptionValidate()
            {
                Menu.SetChecked(MenuItemException, ScriptingDefineSymbolsUtility.Contains(ScriptingDefineSymbolException));
                return true;
            }

            [MenuItem(MenuItemAll, false, 0)]
            public static void ToggleLogAll()
            {
                var all = IsLogAll();

                if (all)
                {
                    foreach (var symbol in ScriptingDefineSymbols)
                        ScriptingDefineSymbolsUtility.Remove(symbol);
                }
                else
                {
                    foreach (var symbol in ScriptingDefineSymbols)
                        ScriptingDefineSymbolsUtility.Add(symbol);
                }
            }

            [MenuItem(MenuItemAll, true)]
            public static bool ToggleLogAllValidate()
            {
                Menu.SetChecked(MenuItemAll, IsLogAll());
                return true;
            }

            private static bool IsLogAll()
            {
                var all = true;

                foreach (var symbol in ScriptingDefineSymbols)
                {
                    if (ScriptingDefineSymbolsUtility.Contains(symbol))
                        continue;

                    all = false;
                    break;
                }

                return all;
            }
        }
    }
}